package panda

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"time"
)

// var _log = logger.GetLogInfo()
// var logger = log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Llongfile)

// Input 函数接收不定数量的字符串参数 prompt，返回一个字符串
//
// 参数：
//
//	prompt: 可选的字符串切片，如果提供了该参数，则会使用第一个元素作为提示信息，
//	        否则使用默认提示信息 "Input Content: "
//
// 返回值：
//
//	用户输入的字符串，如果输入过程中出现错误则返回空字符串
func Input(prompt ...string) string {
	pro := "Input Content: "
	if len(prompt) > 0 {
		pro = prompt[0]
	}
	fmt.Printf("%s", pro)
	reader := bufio.NewReader(os.Stdin)
	input, err := reader.ReadString('\n')
	input = strings.TrimSpace(input)
	fmt.Printf("[%s]\n", input)
	if err != nil {
		fmt.Println("Input Error!", err)
		return ""
	}
	return input
}

// Cmd 函数执行传入的命令并返回命令的输出结果
//
// 参数:
// strs: 要执行的命令字符串，多个参数之间用空格分隔
//
// 返回值:
// 返回命令的输出结果字符串
func Cmd(strs string) string {
	args := strings.Split(strs, " ")
	cmd := exec.Command(args[0], args[1:]...)
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		fmt.Println(err)
	}
	outstr := strings.TrimSpace(out.String())
	fmt.Printf("%s\n", outstr)
	return outstr
}

// RunNowDir 函数用于将当前工作目录更改为调用此函数的文件的目录，并打印当前工作目录。
func RunNowDir() {
	_, currentFile, _, _ := runtime.Caller(1) // 0 表示当前调用位置
	dir := filepath.Dir(currentFile)          // 提取目录部分
	_log.Println("当前文件目录:", dir)
	// 修改工作目录
	if err := os.Chdir(dir); err != nil {
		_log.Fatal("修改工作目录失败")
	}
	// 验证当前目录
	currentDir, _ := os.Getwd()
	log.Printf("当前工作目录:%s", currentDir) // 输出: /path/to/your/directory
}

// JsonToFile 将任意类型的字典编码为JSON格式并写入指定文件中
//
// 参数：
//
//	dicts any: 要编码的字典数据
//	fileName string: 输出文件的名称
//
// 返回值：
//
//	error: 如果操作成功，返回nil；否则返回错误信息
func JsonToFile(dicts any, fileName string) error {
	// 编码为JSON字节切片
	jsonData, err := json.MarshalIndent(dicts, "", "  ")
	if err != nil {
		panic("编码失败: " + err.Error())
	}
	// 写入文件（覆盖模式）
	err = os.WriteFile(fileName, jsonData, 0644)
	if err != nil {
		panic("写入失败: " + err.Error())
	}
	return nil
}

// FileToJsonMap 将文件名作为参数传入，返回文件内容解析成的map[string]any类型
//
// 参数:
//
//	fileName: string - 文件名
//
// 返回值:
//
//	map[string]any - 文件内容解析成的map[string]any类型
//
// 示例:
//
//	var result = FileToJsonMap("example.json")
//	fmt.Println(result)
func FileToJsonMap(fileName string) any {
	// 读取文件内容
	jsonData, err := os.ReadFile(fileName)
	if err != nil {
		panic("读取失败: " + err.Error())
	}
	var types map[string]any

	err = json.Unmarshal(jsonData, &types)
	if err != nil {
		panic("解码失败: " + err.Error())
	}
	fmt.Println(types)
	return types
}

// GetMapValue 根据给定的键从映射中获取值
//
// 参数:
//
//	maps: 包含键值对的映射，类型为any
//	key: 要查找的键，类型为string
//
// 返回值:
//
//	返回与键对应的值，类型为any。如果键不存在，则返回nil
func GetMapValue(maps any, key string) any {
	newMap := maps.(map[string]any)
	return newMap[key]
}

// MapToStruct 是一个泛型函数，用于将任意类型的数据（data）转换为目标结构体（target）
//
// 参数：
// - data: 任意类型的数据，需要转换为结构体
// - target: 目标结构体指针，用于存储转换后的数据
//
// 返回值：
// - 如果转换成功，则返回 nil
// - 如果转换失败，则返回错误信息
func MapToStruct[T any](data any, target *T) error {
	// 1. Map → JSON
	jsonBytes, err := json.Marshal(data)
	if err != nil {
		return fmt.Errorf("JSON序列化失败: %w", err)
	}
	// 2. JSON → 结构体
	if err := json.Unmarshal(jsonBytes, target); err != nil {
		return fmt.Errorf("JSON反序列化失败: %w", err)
	}
	return nil
}

// TrackTime 函数用于测量并打印给定函数的执行时间
//
// 参数:
//   - name string: 函数的名称，用于打印日志
//   - f func(): 需要测量执行时间的函数
//
// 返回值:
//
//	无
func TrackTime(name string, f func()) {
	start := time.Now()
	defer func() {
		fmt.Printf("[%s] took: %v\n", name, time.Since(start))
	}()
	f()
}
